`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: FPGA/IC
// Engineer: Tony guan
// 
// Create Date: 2024/4/9 10:45:30
// Design Name: udp
// Module Name: eth_udp_test
// Project Name: udp image transmission
// Target Devices: FPGA zc7a35tfgg484-2
// Tool Versions: vivado 2023.2
// Description: 
// Dependencies: send ov5640 data to PC or UC
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module eth_top#(
    parameter
            BOARD_MAC = 48'h00_11_22_33_44_55,   
            BOARD_IP = {8'd192,8'd168,8'd1,8'd10},
            DES_IP = {8'd192,8'd168,8'd1,8'd102},
            DES_MAC   = 48'hff_ff_ff_ff_ff_ff
)(
    input        eth_rxc         ,
    input        eth_rxctl       ,
    input [3:0]  eth_rxd         ,
    input        sys_rst_n       ,   // s0
    input        key_eth_rst_n   ,   // s1 
    input        key_arp_req     ,   // s2 
    input        key_icmp_req    ,   // s3
    input        key_udp_tx      ,   // s4
    input        tx_start        ,
    input [7:0]  udp_fifo_rd_data,
    input [15:0] len_udp_data    ,
    input [15:0] rd_data_count   ,
    output       udp_fifo_rd_en  ,
    output [7:0] udp_rx_data     ,
    output       eth_txc         ,
    output       eth_txctl       ,
    output [3:0] eth_txd         ,
    output       eth_rst_n       ,
    output [3:0] led             ,   // [7:4] rx [3:0] tx
    output       udp_tx_done
    );

// wire define
wire locked;
wire clk;
wire clk_o;
/***************************************************************
                            main code
***************************************************************/
assign eth_rst_n = 1'd1;

clk_wiz_eth u_eth_clk(
    .clk_out1   (clk_o),            // output clk_out1
    .reset      (~sys_rst_n),       // input reset
    .locked     (locked),           // output locked
    .clk_in1    (eth_rxc)           // input clk_in1
);

BUFG u_bufg(
    .O  (clk),
    .I  (clk_o)
);

wire gmii_tx_en;
wire [7:0] gmii_tx_data;
wire gmii_rx_en;
wire [7:0] gmii_rx_data;

rgmii_gmii_handle u_rgmii_gmii_handle(
    .rgmii_rx_clk   (clk),          // input 1bit rgmii clk(eth_rxc)
    .rgmii_rx_ctl   (eth_rxctl),    // input 1bit rgmii rx en ^ err
    .rgmii_rx_data  (eth_rxd),      // input 4bit data (double edge data)

    .gmii_tx_en     (gmii_tx_en),   // output 1bit tx en
    .gmii_tx_data   (gmii_tx_data), // output 8bit tx data
    .rgmii_tx_clk   (eth_txc),      // output 1bit tx clock
    .rgmii_tx_ctl   (eth_txctl),    // output 1bit tx enable
    .rgmii_tx_data  (eth_txd),      // output 4bit tx data(double edge data)
    .gmii_rx_clk    (gmii_rx_clk),  // output 1bit rx clock
    .gmii_rx_en     (gmii_rx_en),   // output 1bit rx enable
    .gmii_rx_data   (gmii_rx_data)  // output 8bit rx data
);

wire arp_tx_done;
wire arp_tx_busy;
wire arp_gmii_tx_en;
wire [7:0] arp_gmii_tx_data;
wire [31:0] arp_rx_ip;
wire [47:0] arp_rx_mac;
arp#(
    .BOARD_IP(BOARD_IP),
    .BOARD_MAC(BOARD_MAC),
    .DES_IP(DES_IP),
    .DES_MAC(DES_MAC)
) u_arp(
    .rst_n          (sys_rst_n),
    .gmii_rx_clk    (clk),
    .gmii_rx_en     (gmii_rx_en),
    .gmii_rx_data   (gmii_rx_data),
    .key_req        (key_arp_req),
    
    .arp_rx_done    (arp_rx_done),
    .arp_tx_done    (arp_tx_done),
    .arp_tx_busy    (arp_tx_busy),
    .gmii_tx_en     (arp_gmii_tx_en),
    .gmii_tx_data   (arp_gmii_tx_data),
    .source_ip      (arp_rx_ip),
    .source_mac     (arp_rx_mac)
);

//wire icmp_tx_done;
//wire icmp_tx_busy;
//wire icmp_gmii_tx_en;
//wire [7:0] icmp_gmii_tx_data;

//icmp#(
//    .BOARD_IP(BOARD_IP),
//    .BOARD_MAC(BOARD_MAC)
//) u_icmp(
//    .gmii_rx_clk        (clk),
//    .rst_n              (sys_rst_n),
//    .gmii_rx_en         (gmii_rx_en),
//    .gmii_rx_data       (gmii_rx_data),
//    .des_ip             (arp_rx_ip),
//    .des_mac            (arp_rx_mac),
//    .key_req            (key_icmp_req),

//    .icmp_tx_done       (icmp_tx_done),
//    .icmp_tx_busy       (icmp_tx_busy),
//    .gmii_tx_en         (icmp_gmii_tx_en),
//    .gmii_tx_data       (icmp_gmii_tx_data),
//    .fifo_rd_rst_busy   (icmp_fifo_rd_rst_busy),
//    .fifo_wr_rst_busy   (icmp_fifo_wr_rst_busy)
//);


wire udp_gmii_tx_en;
wire [7:0] udp_gmii_tx_data;
wire udp_tx_busy;
wire udp_rx_done;
udp#(
    .BOARD_IP(BOARD_IP),
    .BOARD_MAC(BOARD_MAC)
) u_udp(
    .clk                (clk),
    .rst_n              (sys_rst_n),
    .gmii_rx_en         (gmii_rx_en),
    .gmii_rx_data       (gmii_rx_data),
    .udp_key_tx         (key_udp_tx),
    .des_ip             (arp_rx_ip),
    .des_mac            (arp_rx_mac),
    .tx_start           (tx_start),
    .udp_fifo_rd_data   (udp_fifo_rd_data),
    .len_udp_data       (len_udp_data),
    .udp_fifo_rd_en     (udp_fifo_rd_en),
    .rd_data_count      (rd_data_count),

    .gmii_tx_en         (udp_gmii_tx_en),
    .gmii_tx_data       (udp_gmii_tx_data),
    .udp_tx_done        (udp_tx_done),
    .udp_tx_busy        (udp_tx_busy),
    .udp_rx_done        (udp_rx_done),
    .udp_rx_data        (udp_rx_data)
);

tx_ctrl u_tx_ctrl(
    .clk                 (clk),
    .rst_n               (sys_rst_n),
    .arp_gmii_tx_data    (arp_gmii_tx_data),
    .arp_gmii_tx_en      (arp_gmii_tx_en),
    .arp_tx_done         (arp_tx_done),
    .arp_tx_busy         (arp_tx_busy),
    .arp_rx_done         (arp_rx_done),
    .udp_gmii_tx_data    (udp_gmii_tx_data),
    .udp_gmii_tx_en      (udp_gmii_tx_en),
    .udp_tx_done         (udp_tx_done),
    .udp_tx_busy         (udp_tx_busy),
    .udp_rx_done         (udp_rx_done),

    .gmii_tx_en          (gmii_tx_en),
    .gmii_tx_data        (gmii_tx_data),
    .led                 (led)
);
endmodule
